import os

import prettytable

from thread_project.demo02 import utils
from thread_project.demo02.const import CalcType
from thread_project.demo02.modules.download import Downloader
from thread_project.demo02.modules.hasher import Hasher
from thread_project.demo02.modules.storager import Storager
from thread_project.demo02.utils import Timer


class Scheduler:
    def __init__(self):
        self.downloader = Downloader()
        self.hasher = Hasher()
        self.storager = Storager()

    def _wrap_path(self, md5):
        file_name = "{}.jpg".format(md5)
        STORAGE_PATH = os.path.join(".", "image")
        path = os.path.join(STORAGE_PATH, file_name)
        return path

    def set_calc_type(self, type_):
        self.downloader.set_calc_type(type_)
        self.hasher.set_calc_type(type_)
        self.storager.set_calc_type(type_)

    def process(self):
        time_static = {}
        time_static["network_time"] = []
        time_static["cpu_time"] = []
        time_static["disk_time"] = []

        timer = Timer()

        timer.tick()
        url_list = utils.url_list()
        time_cost = timer.tock()
        # time_static["network_time"].append(time_cost)

        timer.tick()
        content_list = self.downloader.process(url_list)
        time_cost = timer.tock()
        time_static["network_time"].append(time_cost)

        timer.tick()
        md5_list = self.hasher.process(content_list)
        time_cost = timer.tock()
        time_static["cpu_time"].append(time_cost)

        for md5 in md5_list:
            print(md5)

        item_list = []
        for content, md5 in zip(content_list, md5_list):
            path = self._wrap_path(md5)
            item = (content, path)
            item_list.append(item)

        timer.tick()
        self.storager.process(item_list)
        time_cost = timer.tock()
        time_static["disk_time"].append(time_cost)

        return time_static

    def statictics(self, single_log, multi_log):
        table = prettytable.PrettyTable(["类型", "单线程总耗时", "多线程总耗时", "多线程提升率"])
        network_row = ["network"]
        cpu_row = ["cpu"]
        disk_row = ["disk"]
        # 单线程数据
        network_row.append(single_log["network_time"][0])
        cpu_row.append(single_log["cpu_time"][0])
        disk_row.append(single_log["disk_time"][0])

        # table.add_row(network_row)
        # table.add_row(cpu_row)
        # table.add_row(disk_row)

        # 多线程数据
        network_row.append(multi_log["network_time"][0])
        cpu_row.append(multi_log["cpu_time"][0])
        disk_row.append(multi_log["disk_time"][0])

        # 多线程提升率
        time_ = single_log["network_time"][0] - multi_log["network_time"][0]
        lift_rate = "%.4f%%" % ((time_ / single_log["network_time"][0]) * 100)
        network_row.append(lift_rate)

        time_ = single_log["cpu_time"][0] - multi_log["cpu_time"][0]
        lift_rate = "%.4f%%" % ((time_ / single_log["cpu_time"][0]) * 100)
        cpu_row.append(lift_rate)

        time_ = single_log["disk_time"][0] - multi_log["disk_time"][0]
        lift_rate = "%.4f%%" % ((time_ / single_log["disk_time"][0]) * 100)
        disk_row.append(lift_rate)

        table.add_row(network_row)
        table.add_row(cpu_row)
        table.add_row(disk_row)

        print(table)


if __name__ == "__main__":
    test = Scheduler()
    # 单线程运行
    # test.set_calc_type(CalcType.SingleThread)
    # single_time = test.process()
    # test.statictics(single_time)
    # 多线程运行
    # test.set_calc_type(CalcType.MultiThread)
    # multi_time = test.process()
    # test.statictics(single_time, multi_time)
    # 多进程运行
    test.set_calc_type(CalcType.MultiProcess)
    multi_process_time = test.process()
